<?php


namespace app\common;

use AlibabaCloud\Oss\V2 as Oss;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\HandlerStack;

class OssV2Upload
{
    protected Oss\Client $client;
    protected mixed $config;


    public function __construct()
    {
        $this->config = config('app.oss');
        // 配置OSS客户端
        $credentialsProvider = new Oss\Credentials\StaticCredentialsProvider(
            $this->config['access_key_id'],
            $this->config['access_key_secret']
        );
        $cfg = Oss\Config::loadDefault();
        $cfg->setCredentialsProvider($credentialsProvider)
            ->setRegion('cn-beijing') // 设置Bucket所在的地域
            ->setEndpoint($this->config['upload_url']); // 设置访问域名
        $handler = HandlerStack::create(new CurlHandler());
        $this->client = new Oss\Client($cfg, ['handler' => $handler]);
    }

    public function getUploadId($key): Oss\Models\InitiateMultipartUploadResult
    {
        // 初始化分片上传任务
        return $this->client->initiateMultipartUpload(
            new Oss\Models\InitiateMultipartUploadRequest(
                bucket: $this->config['bucket_name'],
                key: $key,
            )
        );
    }

    public function chunkUpload($file, $upload_id, $num, $save_name): Oss\Models\UploadPartResult
    {
        return $this->client->uploadPart(
            new Oss\Models\UploadPartRequest(
                bucket: $this->config['bucket_name'],
                key: $save_name,
                partNumber: $num, // 当前分片编号
                uploadId: $upload_id, // 初始上传任务返回的uploadId
                contentLength: null, // 可选：分片内容长度
                contentMd5: null, // 可选：分片内容的MD5校验值
                trafficLimit: null, // 可选：流量限制
                requestPayer: null, // 可选：请求支付方
                body: new \GuzzleHttp\Psr7\LimitStream(new \GuzzleHttp\Psr7\LazyOpenStream($file, 'rb')) // 读取当前分片的数据
            )
        );
    }

    public function completeMultipartUpload($upload_id, $part, $save_name): Oss\Models\CompleteMultipartUploadResult
    {
        $parts = [];
        foreach ($part as $i => $eTag) {
            $parts[] = new Oss\Models\UploadPart(
                partNumber: ($i + 1), // 分片编号
                etag: $eTag // 分片上传后返回的ETag值
            );
        }
        return $this->client->completeMultipartUpload(
            new Oss\Models\CompleteMultipartUploadRequest(
                bucket: $this->config['bucket_name'],
                key: $save_name,
                uploadId: $upload_id, // 初始上传任务返回的uploadId
                acl: null, // 可选：设置对象的访问控制列表（ACL）
                completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
                    parts: $parts // 提交所有分片的上传结果
                )
            )
        );
    }
}